package com.kefu.z.intermediator;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@Service
public class WebSocketHandler extends AbstractWebSocketHandler {
	
	
	
	public WebSocketHandler() {
		
	}

	static Map<String,WebSocketSession> sessionPools=new HashMap<String, WebSocketSession>();

	/**
	 * 在连接建立
	 */
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		sessionPools.put(session.getId(),session);
	}
	
	/**
	 * 处理传输错误
	 */
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		System.out.println("handleTransportError");
	}
	/**
	 * 连接关闭后
	 */
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		System.out.println("afterConnectionClosed");
		//通知关联客服,当前客户下线
	   if(userPools.get(session.getId()).getSystem()!=null){
			//客户下线
			ResultRequest kh_rr=new ResultRequest();
			kh_rr.setMethod(ResultMethodType.KEHU_XIAXIAN);
			kh_rr.setState("success");
			kh_rr.setForm(userPools.get(session.getId()));
			TextMessage r=new TextMessage(JSONObject.toJSONString(kh_rr));
			if(sessionPools.get(userPools.get(session.getId()).getSystem().getSessionId())!=null)
			{
				sessionPools.get(userPools.get(session.getId()).getSystem().getSessionId()).sendMessage(r);//获取客户会话并发送
			}
		}
		//清除池内缓存
		sessionPools.remove(session.getId());
		userPools.remove(session.getId());
		
	}
	static Map<String,Mine> userPools=new HashMap<String,Mine>();
	/**
	 * 处理文本请求
	 */
	protected void handleTextMessage(WebSocketSession session,  
            TextMessage message) throws Exception {
		String body=message.getPayload();//获取请求内容
		System.out.println("body:"+body);
		JSONObject json=JSONObject.parseObject(body);//转换内容为json对象
		SocketRequest sr=json.toJavaObject(SocketRequest.class);
		switch (sr.getMethod()) {
		case MethodType.SYSTEM_INLINE:
			//客服上线
			/*判断写入或更新客服状态*/
			if(userPools.get(session.getId())==null){
				userPools.put(session.getId(),sr.getParams().getForm());
			}else{
				Mine sx_mine=userPools.get(session.getId());
				sx_mine.setStatus("online");
				userPools.put(session.getId(),sx_mine);
			}
			/*后续写入用户session id*/
			Mine m=userPools.get(session.getId());
			m.setSessionId(session.getId());
			userPools.put(session.getId(),m);
			/* 响应客服端上线提醒 */
			ResultRequest rr=new ResultRequest();
			rr.setMethod(ResultMethodType.KEFU_SHANGXIAN);
			rr.setState("success");
			TextMessage result=new TextMessage(JSONObject.toJSONString(rr));
			session.sendMessage(result);
			/*向客户端推送上线消息*/
			Map<String,Mine> sx_customers=userPools.get(session.getId()).getCustomer();
			System.out.println(sx_customers.size());
			for(String key:sx_customers.keySet()){
				ResultRequest kh_rr=new ResultRequest();
				kh_rr.setMethod(ResultMethodType.KEFU_SHANGXIAN);
				kh_rr.setState("success");
				kh_rr.setForm(userPools.get(session.getId()));
				TextMessage r=new TextMessage(JSONObject.toJSONString(kh_rr));
				sessionPools.get(key).sendMessage(r);//获取客户会话并发送
			}
			break;
		case MethodType.SYSTEM_OFFLINE:
			//客服下线
			/*更新客服状态*/
			Mine mine=userPools.get(session.getId());
			mine.setStatus("offline");
			userPools.put(session.getId(),mine);
			/* 响应客服端下线提醒 */
			ResultRequest xx_rr=new ResultRequest();
			xx_rr.setMethod(ResultMethodType.KEFU_XIAXIAN);
			xx_rr.setState("success");
			TextMessage xx_result=new TextMessage(JSONObject.toJSONString(xx_rr));
			session.sendMessage(xx_result);
			/*向客户端推送客服下线信息*/
			Map<String,Mine> xx_customers=mine.getCustomer();
			for(String key:xx_customers.keySet()){
				ResultRequest kh_rr=new ResultRequest();
				kh_rr.setMethod(ResultMethodType.KEFU_XIAXIAN);
				kh_rr.setState("success");
				kh_rr.setForm(userPools.get(session.getId()));
				TextMessage r=new TextMessage(JSONObject.toJSONString(kh_rr));
				sessionPools.get(key).sendMessage(r);//获取客户会话并发送
			}
			break;
		case MethodType.UPDATE_USER_INFO:
			//更新用户信息
			/*获取用户信息*/
			Mine update_user_info=userPools.get(session.getId());
			/*比对修改*/
			Mine update_form=sr.getParams().getForm();
			update_user_info.setAvatar(update_form.getAvatar());
			update_user_info.setId(update_form.getId());
			update_user_info.setSign(update_form.getSign());
			update_user_info.setStatus(update_form.getStatus());
			update_user_info.setUsername(update_form.getUsername());
			/*更新*/
			userPools.put(session.getId(),update_user_info);
			/* 响应更新结果  */
			ResultRequest update_rr=new ResultRequest();
			update_rr.setMethod(ResultMethodType.UPDATE_USER_INFO);
			update_rr.setState("success");
			TextMessage update_result=new TextMessage(JSONObject.toJSONString(update_rr));
			session.sendMessage(update_result);
			break;
		case MethodType.USER_ONLINE:
			//客户端上线
			/*将用户信息写入池中 ,由于客户端没有隐身功能,故不需要做上下线状态判断。*/
			Mine import_user=sr.getParams().getForm();
			import_user.setNickName("访客"+System.currentTimeMillis());
			import_user.setSessionId(session.getId());
			userPools.put(session.getId(),import_user);
			/*分配在线客服*/
			Mine fp_online_systems=findOnLineSystemToMinCustomer();
			if(fp_online_systems==null){
				//没有找到在线客服的情况下,给客户端回显
				ResultRequest kh_rr=new ResultRequest();
				kh_rr.setMethod(ResultMethodType.NULL_SYSTEM);
				kh_rr.setState("success");
				TextMessage r=new TextMessage(JSONObject.toJSONString(kh_rr));
				session.sendMessage(r);//获取客户会话并发送
			}else{
				/*获取用户 Mine,更新用户绑定客服*/
				Mine now_user_mine=userPools.get(session.getId());
				/*写入客服信息*/
				now_user_mine.setSystem(fp_online_systems);
				now_user_mine.setSystem_session_id(fp_online_systems.getSessionId());
				/*更新*/
				userPools.put(session.getId(),now_user_mine);
				/*更新客服下属用户 */
				fp_online_systems.addCustomer(session.getId(),now_user_mine);
				userPools.put(fp_online_systems.getSessionId(),fp_online_systems);
				/*推送给客服新客户接入*/
				ResultRequest kh_jr_rr=new ResultRequest();
				kh_jr_rr.setMethod(ResultMethodType.JOIN_CHAT);
				kh_jr_rr.setState("success");
				kh_jr_rr.setForm(now_user_mine);
				kh_jr_rr.setToJson(JSON.toJSONString(now_user_mine.getSystem()));
				TextMessage kh_jr_r=new TextMessage(JSONObject.toJSONString(kh_jr_rr));
				/*推送给客户,已经连接新客服*/
				session.sendMessage(kh_jr_r);
				TextMessage kh_jr_r1=new TextMessage(JSONObject.toJSONString(kh_jr_rr));
				sessionPools.get(now_user_mine.getSystem_session_id()).sendMessage(kh_jr_r1);//获取客服会话并推送
			}
			break;
		case MethodType.SEND_INFO:
			String sessionId=findUserMineSessionId(sr.getParams().getTo());
			System.out.println("TO:"+sessionId);
			ResultRequest zf_req=new ResultRequest();
			zf_req.setForm(sr.getParams().getForm());
			zf_req.setToJson(JSON.toJSONString(sr.getParams().getTo()));
			zf_req.setTo(sr.getParams().getTo());
			zf_req.setState("success");
			zf_req.setContent(sr.getParams().getContent());
			zf_req.setMethod(ResultMethodType.GET_MESSAGE);
			TextMessage zhuanfa=new TextMessage(JSON.toJSONString(zf_req));
			sessionPools.get(sessionId).sendMessage(zhuanfa);
			break;
		case MethodType.GB_INFO:
			/*向客户端推送客服下线信息*/
			Mine gb_mine=userPools.get(session.getId());
			Map<String,Mine> gb_customers=gb_mine.getCustomer();
			for(String key:gb_customers.keySet()){
				ResultRequest gb_req=new ResultRequest();
				gb_req.setForm(sr.getParams().getForm());
				gb_req.setToJson(JSON.toJSONString(userPools.get(key)));
				gb_req.setTo(userPools.get(key));
				gb_req.setState("success");
				gb_req.setContent(sr.getParams().getContent());
				gb_req.setMethod(ResultMethodType.GET_MESSAGE);
				TextMessage r=new TextMessage(JSON.toJSONString(gb_req));
				sessionPools.get(key).sendMessage(r);//获取客户会话并发送
			}
			break;
		default:
			System.err.println("Error:method is undefined.");
			break;
		}
    }
	private String findUserMineSessionId(Mine mine){
		for(String key:userPools.keySet()){
			if(userPools.get(key).getId().equals(mine.getId())){
				return key;
			}
		}
		return null;
	}

	private Mine findOnLineSystemToMinCustomer() {
		Mine r=null;
		for(String key:userPools.keySet()){
			Mine mine=userPools.get(key);
			if(mine.getType().equals("system")){
				if(r==null){
					r=mine;
					continue;
				}
				if(mine.getCustomer().size()<=r.getCustomer().size()){
					r=mine;
				}
			}
		}
		return r;
	}

}